package cn.mill.support;

import java.io.InputStream;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.mill.common.Context;
import cn.mill.common.Strategy;
import cn.mill.common.annotation.SPI;
import cn.mill.common.data.DataCommon;
import cn.mill.common.data.Item;
import cn.mill.common.data.ItemArray;
import cn.mill.common.message.Message;
import cn.mill.core.DefaultData;
import cn.mill.core.DefaultMessage;

@SPI("xml")
public class XmlStrategy implements Strategy<String, InputStream> {
	private static Logger logger = LoggerFactory.getLogger(XmlStrategy.class);
	// private static final String ROOT = "resp";
	
	@Override
	public Message<String> write(Context invoke, ItemArray itemArray) {
		DefaultMessage<String> message = new DefaultMessage<String>();
		Document document = DocumentHelper.createDocument();
		// Element root = document.addElement(ROOT);
		message.setDataBlock(document.asXML());
		return message;
	}
	
	@Override
	public DataCommon<ItemArray> read(Context invoke, Message<InputStream> message) {
		DefaultData defaultData = new DefaultData();
		if (message != null && message.getDataBlock() != null) {
			SAXReader reader = new SAXReader();
			ItemArray array = null;
			try {
				Document document = reader.read(message.getDataBlock());
				Element root = document.getRootElement();
				if (this.isSubElement(root)) {
					array = this.builderXMLArray(root);
				} else {
					array = new ItemArray(0);
				}
			} catch (DocumentException e) {
				logger.error("XmlStrategy read", e);
			}
			defaultData.setValue(array);
			defaultData.setFine(true);
		} else {
			defaultData.setFine(false);
		}
		return defaultData;
	}
	
	private ItemArray builderXMLArray(Element data) {
		ItemArray itemArray = new ItemArray();
		if (data != null) {
			List<Element> datas = (List<Element>) data.elements();
			for (Element e : datas) {
				if (this.isSubElement(e)) {
					ItemArray array = this.builderXMLArray(e);
					itemArray.addItem(new Item(null, e.getName(), ItemArray.class, array));
				} else {
					itemArray.addItem(new Item(null, e.getName(), String.class, e.getText()));
				}
			}
		}
		return itemArray;
	}
	
	// private ItemArray builderXMLObject(Element data) {
	// ItemArray itemArray = new ItemArray();
	//
	// return itemArray;
	// }
	
	private boolean isSubElement(Element element) {
		return element.selectNodes("./*").size() > 0;
	}
	
	private boolean isArray(Element element) {
		// element.selectSingleNode(arg0)
		return false;
	}
}
